package com.sf.fy.uav.applet.controller;

import com.alibaba.fastjson.JSONObject;
import com.sf.fy.global.service.GlobalService;
import com.sf.fy.uav.applet.IntraCityServiceClient;
import com.sf.fy.uav.applet.service.OrderService;
import com.sf.fy.uav.common.awt.JwtUtil;
import com.sf.fy.uav.common.awt.RepeatSubmit;
import com.sf.fy.uav.common.enums.ActivityProductTypeEnum;
import com.sf.fy.uav.common.enums.PlatformCodeEnum;
import com.sf.fy.uav.common.request.common.IdRequest;
import com.sf.fy.uav.common.request.order.BatchPreCarrierWaybillRequest;
import com.sf.fy.uav.common.request.order.PreCarrierWaybillRequest;
import com.sf.fy.uav.common.request.order.PrepareOrderForWebForBatchRequest;
import com.sf.fy.uav.common.request.order.PrepareOrderForWebRequest;
import com.sf.fy.uav.common.response.BatchPlaceOrderForWebResponse;
import com.sf.fy.uav.common.response.BatchPlaceOrderResponse;
import com.sf.fy.uav.common.response.order.*;
import com.sf.fy.uav.common.response.user.UserCompanyResponse;
import com.sf.fy.uav.common.utils.BeanUtil;
import com.sf.fy.uav.common.utils.GpsUtil;
import com.sf.fy.uav.common.utils.PhoneEncoderUtil;
import com.sf.fy.uav.common.utils.Rs;
import com.sf.fy.uav.order.service.IOrderInfoService;
import com.sf.fy.uav.rest.SysMapRest;
import com.sf.fy.uav.user.controller.UserCompanyRest;
import com.sf.fy.uav.user.entity.UserCompany;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;


/**
 * @author LTQ
 */
@RestController
@RequestMapping("/sys/order/")
public class OrderController {
    @Autowired
    private IOrderInfoService iOrderInfoService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private GlobalService globalService;

    @Autowired
    private PhoneEncoderUtil phoneEncoderUtil;


    @Autowired
    private IntraCityServiceClient intraCityServiceClient;

    @Autowired
    private SysMapRest sysMapRest;


    @Autowired
    private UserCompanyRest userCompanyRest;


    @Value("${oss.public-path:https://sit-ie-uocs-core-shenzhen-xili1-oss.sit.sf-express.com/v1.2/AUTH_sit-IE-UOCS-CORE/sfosspublic001}")
    private String ossPublicPath;
    private final static Logger logger = LoggerFactory.getLogger(OrderController.class);


    /**
     * 匹配站点
     *
     * @return
     */
    @PostMapping("matching-sites")
    @Operation(tags = "查询是否可以下单", description = "询单")
    public Rs<CarrierWaybillForWebResponse> matchingSites(@RequestBody @Validated PreCarrierWaybillRequest preCarrierWaybillRequest) {
        //获取剩余额度
        BigDecimal availableCredit = orderService.getAvailableCredit();
        preCarrierWaybillRequest.setPlatformCode(PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode());
        CarrierWaybillResponse carrierWaybillResponse = iOrderInfoService.matchingSites(preCarrierWaybillRequest);
        CarrierWaybillForWebResponse carrierWaybillForWebResponse = BeanUtil.copyProperties(carrierWaybillResponse, CarrierWaybillForWebResponse.class);
        carrierWaybillForWebResponse.setAvailableCredit(availableCredit);
        return Rs.success(carrierWaybillForWebResponse);
    }


    /**
     * 下单接口
     *
     * @return
     */
    @PostMapping("place-order-for-web")
    @Operation(tags = "下单", description = "下单")
    //防重不生效
    @RepeatSubmit(interval = 1000, message = "重复提交")
    public Rs<String> placeOrder(@Valid @RequestBody PrepareOrderForWebRequest prepareOrderRequest) {
        return Rs.success(globalService.placeOrderForWeb(prepareOrderRequest));
    }


    @GetMapping("get-user-company-by-user-id")
    @Operation(tags = "通过用户id公司信息", description = "通过用户id公司信息")
    //防重不生效
    public Rs<UserCompanyResponse> getUserCompanyByUserId() {
        String userId = JwtUtil.getUserId();
        UserCompany userCompany = userCompanyRest.getByUserId(userId);
        if (!ObjectUtils.isEmpty(userCompany)) {
            UserCompanyResponse userCompanyResponse = BeanUtil.copyProperties(userCompany, UserCompanyResponse.class);
            userCompanyResponse.setContactPhoneNumber(phoneEncoderUtil.decryptString(userCompanyResponse.getContactPhoneNumber()));
            return Rs.success(userCompanyResponse);
        }
        return Rs.success();
    }


    @PostMapping("batch-matching-sites")
    @Operation(tags = "批量查询是否可以下单", description = "批量查询是否可以下单")
    public Rs<BatchCarrierWaybillForWebRsResponse> batchMatchingSites(@RequestBody @Validated List<BatchPreCarrierWaybillRequest> batchPreCarrierWaybillRequests) {
        BatchCarrierWaybillForWebRsResponse batchCarrierWaybillForWebRsResponse = new BatchCarrierWaybillForWebRsResponse();
        List<BatchCarrierWaybillForWebResponse> batchCarrierWaybillForWebResponses = new ArrayList<>();
        BigDecimal availableCredit = orderService.getAvailableCredit();

        for (BatchPreCarrierWaybillRequest batchPreCarrierWaybillRequest : batchPreCarrierWaybillRequests) {
            BatchCarrierWaybillForWebResponse batchCarrierWaybillForWebResponse = new BatchCarrierWaybillForWebResponse();
            batchCarrierWaybillForWebResponse.setId(batchPreCarrierWaybillRequest.getId());
            try {
                PreCarrierWaybillRequest preCarrierWaybillRequest = BeanUtil.copyProperties(batchPreCarrierWaybillRequest, PreCarrierWaybillRequest.class);
                String receiverDetailAddress = batchPreCarrierWaybillRequest.getReceiverDetailAddress();
                JSONObject jsonObject = sysMapRest.addressResolution(receiverDetailAddress);
                if ("0".equals(jsonObject.getString("status")) && "Success".equals(jsonObject.getString("message"))) {
                    //正常解析
                    System.out.println("");
                    BigDecimal lat = jsonObject.getJSONObject("result").getJSONObject("location").getBigDecimal("lat");
                    BigDecimal lng = jsonObject.getJSONObject("result").getJSONObject("location").getBigDecimal("lng");
                    String province = ((JSONObject) jsonObject.getJSONObject("result").get("address_components")).getString("province");
                    String city = ((JSONObject) jsonObject.getJSONObject("result").get("address_components")).getString("city");
                    String district = ((JSONObject) jsonObject.getJSONObject("result").get("address_components")).getString("district");

                    batchCarrierWaybillForWebResponse.setToProvince(province);
                    batchCarrierWaybillForWebResponse.setToCity(city);
                    batchCarrierWaybillForWebResponse.setToDistrict(district);


                    preCarrierWaybillRequest.setReceiverCity(province + city);
                    double[] transferRs = GpsUtil.gcj02_To_Gps84(lat.doubleValue(), lng.doubleValue());
                    lat = new BigDecimal(transferRs[0]).setScale(5, BigDecimal.ROUND_HALF_UP);
                    lng = new BigDecimal(transferRs[1]).setScale(5, BigDecimal.ROUND_HALF_UP);
                    batchCarrierWaybillForWebResponse.setReceiverLat(lat.toString());
                    batchCarrierWaybillForWebResponse.setReceiverLon(lng.toString());
                    preCarrierWaybillRequest.setReceiverLat(lat.toString());
                    preCarrierWaybillRequest.setReceiverLon(lng.toString());


                    Rs<String> rs = intraCityServiceClient.isPointInPolygon(lng.doubleValue(), lat.doubleValue());
                    if (rs.isFail()) {
                        batchCarrierWaybillForWebResponse.setCanItBeDelivered(false);
                        batchCarrierWaybillForWebResponse.setReasonForNonDelivery("收件地址不在范围内");
                        continue;
                    }

                } else {
                    batchCarrierWaybillForWebResponse.setCanItBeDelivered(false);
                    batchCarrierWaybillForWebResponse.setReasonForNonDelivery("收件人地址解析异常");
                    continue;
                }
                String senderDetailsAddress = batchPreCarrierWaybillRequest.getSenderDetailsAddress();
                jsonObject = sysMapRest.addressResolution(senderDetailsAddress);
                if ("0".equals(jsonObject.getString("status")) && "Success".equals(jsonObject.getString("message"))) {
                    //正常解析
                    BigDecimal lat = jsonObject.getJSONObject("result").getJSONObject("location").getBigDecimal("lat");
                    BigDecimal lng = jsonObject.getJSONObject("result").getJSONObject("location").getBigDecimal("lng");
                    double[] transferRs = GpsUtil.gcj02_To_Gps84(lat.doubleValue(), lng.doubleValue());
                    lat = new BigDecimal(transferRs[0]).setScale(5, BigDecimal.ROUND_HALF_UP);
                    lng = new BigDecimal(transferRs[1]).setScale(5, BigDecimal.ROUND_HALF_UP);
                    batchCarrierWaybillForWebResponse.setSenderLat(lat.toString());
                    batchCarrierWaybillForWebResponse.setSenderLon(lng.toString());


                    String province = ((JSONObject) jsonObject.getJSONObject("result").get("address_components")).getString("province");
                    String city = ((JSONObject) jsonObject.getJSONObject("result").get("address_components")).getString("city");
                    String district = ((JSONObject) jsonObject.getJSONObject("result").get("address_components")).getString("district");

                    batchCarrierWaybillForWebResponse.setFromProvince(province);
                    batchCarrierWaybillForWebResponse.setFromCity(city);
                    batchCarrierWaybillForWebResponse.setFromDistrict(district);
                    preCarrierWaybillRequest.setSenderCity(province + city);
                    preCarrierWaybillRequest.setSenderLat(lat.toString());
                    preCarrierWaybillRequest.setSenderLon(lng.toString());

                    Rs<String> rs = intraCityServiceClient.isPointInPolygon(lng.doubleValue(), lat.doubleValue());
                    if (rs.isFail()) {
                        batchCarrierWaybillForWebResponse.setCanItBeDelivered(false);
                        batchCarrierWaybillForWebResponse.setReasonForNonDelivery("寄件地址不在范围内");
                        continue;
                    }
                } else {
                    batchCarrierWaybillForWebResponse.setCanItBeDelivered(false);
                    batchCarrierWaybillForWebResponse.setReasonForNonDelivery("寄件人地址解析异常");
                    batchCarrierWaybillForWebResponses.add(batchCarrierWaybillForWebResponse);
                    continue;
                }

                preCarrierWaybillRequest.setPlatformCode(PlatformCodeEnum.MONTHLY_SETTLEMENT_PLATFORM.getCode());
                CarrierWaybillResponse carrierWaybillResponse = iOrderInfoService.matchingSites(preCarrierWaybillRequest);


                BeanUtils.copyProperties(carrierWaybillResponse, batchCarrierWaybillForWebResponse);

                batchCarrierWaybillForWebResponse.setCanItBeDelivered(true);
                batchCarrierWaybillForWebResponses.add(batchCarrierWaybillForWebResponse);
            } catch (Exception e) {
                batchCarrierWaybillForWebResponse.setCanItBeDelivered(false);
                batchCarrierWaybillForWebResponse.setReasonForNonDelivery(e.getMessage());
                batchCarrierWaybillForWebResponses.add(batchCarrierWaybillForWebResponse);
//                if (ErrorEnum.INSUFFICIENT_CREDIT_LIMIT.getErrCode() == e.) {
//                    break;
//                }
            }
        }
        batchCarrierWaybillForWebRsResponse.setAvailableCredit(availableCredit);
        batchCarrierWaybillForWebRsResponse.setBatchCarrierWaybillForWebResponses(batchCarrierWaybillForWebResponses);
        return Rs.success(batchCarrierWaybillForWebRsResponse);
    }


    @PostMapping("batch-place-order-for-web")
    @Operation(tags = "批量下单", description = "批量下单")
    @RepeatSubmit(interval = 1000, message = "重复提交")
    public Rs<BatchPlaceOrderResponse> batchPlaceOrder(@RequestBody @Validated List<PrepareOrderForWebForBatchRequest> prepareOrderForWebForBatchRequests) {
        BatchPlaceOrderResponse batchPlaceOrderResponse = new BatchPlaceOrderResponse();
        batchPlaceOrderResponse.setTotal(prepareOrderForWebForBatchRequests.size());
        List<BatchPlaceOrderForWebResponse> batchPlaceOrderForWebResponses = new ArrayList<>(prepareOrderForWebForBatchRequests.size());
        AtomicReference<Integer> successCount = new AtomicReference<>(0);
        prepareOrderForWebForBatchRequests.forEach(prepareOrderForWebForBatchRequest -> {
            BatchPlaceOrderForWebResponse batchPlaceOrderForWebResponse = new BatchPlaceOrderForWebResponse();
            batchPlaceOrderForWebResponse.setId(prepareOrderForWebForBatchRequest.getId());
            String fromProvince = prepareOrderForWebForBatchRequest.getFromProvince();
            String fromCity = prepareOrderForWebForBatchRequest.getFromCity();
            String toProvince = prepareOrderForWebForBatchRequest.getToProvince();
            String toCity = prepareOrderForWebForBatchRequest.getToCity();
            PrepareOrderForWebRequest prepareOrderForWebRequest = BeanUtil.copyProperties(prepareOrderForWebForBatchRequest, PrepareOrderForWebRequest.class);
            try {
                PreCarrierWaybillRequest preCarrierWaybillRequest = BeanUtil.copyProperties(prepareOrderForWebForBatchRequest, PreCarrierWaybillRequest.class);
                preCarrierWaybillRequest.setIsCalculatePrice(false);
                preCarrierWaybillRequest.setSenderCity(fromProvince + fromCity);
                preCarrierWaybillRequest.setReceiverCity(toProvince + toCity);
                this.matchingSites(preCarrierWaybillRequest);
                //记录产品类型
                Byte productType = ActivityProductTypeEnum.CROSS_REGION.getCode();
                if (fromProvince.equals(toProvince) && fromCity.equals(toCity)) {
                    productType = ActivityProductTypeEnum.LOCAL.getCode();
                }
                prepareOrderForWebRequest.setProductType(productType);
                String tcWaybillNo = globalService.placeOrderForWeb(prepareOrderForWebRequest);
                successCount.getAndSet(successCount.get() + 1);
                batchPlaceOrderForWebResponse.setCanItBeDelivered(true);
                batchPlaceOrderForWebResponse.setTcWayBillNo(tcWaybillNo);
            } catch (Exception ex) {
                String msg;
                if (ObjectUtils.isEmpty(ex.getCause())) {
                    msg = ex.getMessage();
                } else {
                    msg = ex.getCause().getMessage();
                }
                batchPlaceOrderForWebResponse.setCanItBeDelivered(false);
                batchPlaceOrderForWebResponse.setReasonForNonDelivery(msg);
            }
            batchPlaceOrderForWebResponses.add(batchPlaceOrderForWebResponse);

        });
        batchPlaceOrderResponse.setBatchPlaceOrderForWebResponses(batchPlaceOrderForWebResponses);
        batchPlaceOrderResponse.setSuccessNum(successCount.get());
        batchPlaceOrderResponse.setFailNum(prepareOrderForWebForBatchRequests.size() - successCount.get());
        return Rs.success(batchPlaceOrderResponse);
    }


    @PostMapping("cancel-order")
    @RepeatSubmit(interval = 2000, message = "重复提交")
    @Operation(tags = "取消订单", description = "取消订单")
    public Rs<Date> cancelOrder(@RequestBody @javax.validation.Valid IdRequest idRequest) {
        return Rs.success(orderService.cancelExpressOrder(idRequest.getId(), idRequest.getProcessedBy()));
    }


    @PostMapping("/get-print-data")
    @Operation(tags = "获取打印数据", description = "获取打印数据")
    public Rs<List<PrintDataResponse>> getPrintData(@RequestBody Set<String> tcWaybillNos) {
        return Rs.success(orderService.getPrintData(tcWaybillNos));
    }
}
